#include <stdio.h>

/*
 *	2016/9/29 yu	liang.
 */

void test_one(void)
{
    int i=1;  
    char *p=(char *)&i;  

    if(*p==1)    
           printf("Little_endian\n");		// Little_endian
    else
           printf("Big_endian\n");		
}

int checkCPU()
{
    {
	   union w
	   {  
			  int a;
			  char b;
	   } c;

	   c.a = 1;

	   return(c.b ==1);	// [little endian]
    }
}

/* 
 * 高字节存储在高地址是小端，高字节存储在低地址是大端 
 */
void test_two()
{
    int *a = (int *)1;			//	内存表示为0x00000001.指向编号为 1 的地址

   if ((unsigned long)(char*)&a[3] == 1) {	// &a[3] = &a + 3 = &a + sizeof(int) * 3 = a + 12 ====> 1 + 12 = 0xD, 见 c/array/slipt.c 验证
        printf("big\n");
   }
   else {
        printf("small\n");
   }

	// 0x1 0x5 0x9 0xd 0x11 0x15
	printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (unsigned int)(long)&a[0], (unsigned int)(long)&a[1],
											  (unsigned int)(long)&a[2], (unsigned int)(long)&a[3], 
											  (unsigned int)(long)&a[4], (unsigned int)(long)&a[5]); 
}
 
void test_thr()
{
    union _test
    {
       int a;
       short b;
    }test;

    test.a = 0x12345678;

    if(test.b == 0x1234)
      printf("big\n");

    if(test.b == 0x5678)
       printf("small\n");
}

typedef unsigned char BYTE;
int test_four()
{
	unsigned int num,*p;

	p = &num;

	num = 0;

	*(BYTE *)p = 0xff;

	if(num == 0xff) {
		printf("The endian of cpu is little\n");
	}
	else {		//	num == 0xff000000
		printf("The endian of cpu is big\n");
	}
	return 0;
}


int main(void)
{
	int ret = -1;

   test_one();	

   ret = checkCPU();
   if (ret == 1)
	   printf("[little endian]\n");	// [little endian]
   else if (ret == 0) 
	   printf("[big endian]\n");

   test_two();	// small
   test_thr();	// small
   test_four();	// The endian of cpu is little


    return 0;
}

#if 0
/*
 * intel
 */


/*
 * arm v8
 */
int test_one(void)
{
  400590:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400594:	910003fd 	mov	x29, sp
    int i=1;  
  400598:	52800020 	mov	w0, #0x1                   	// #1
  40059c:	b90017a0 	str	w0, [x29, #20]              ; i 
    char *p=(char *)&i;  
  4005a0:	910053a0 	add	x0, x29, #0x14 ; i address
  4005a4:	f9000fa0 	str	x0, [x29, #24] ; x0 ---> x29+24

    if(*p==1)    
  4005a8:	f9400fa0 	ldr	x0, [x29, #24] ; p
  4005ac:	39400000 	ldrb	w0, [x0]   ; *p
  4005b0:	7100041f 	cmp	w0, #0x1
  4005b4:	540000a1 	b.ne	4005c8 <test_one+0x38>  // b.any
           printf("Little_endian\n");		// Little_endian
  4005b8:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  4005bc:	911fe000 	add	x0, x0, #0x7f8
  4005c0:	97ffff9c 	bl	400430 <puts@plt>
  4005c4:	14000004 	b	4005d4 <test_one+0x44>
    else
           printf("Big_endian\n");		// Big_endian
  4005c8:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  4005cc:	91202000 	add	x0, x0, #0x808
  4005d0:	97ffff98 	bl	400430 <puts@plt>
}
  4005d4:	d503201f 	nop
  4005d8:	a8c27bfd 	ldp	x29, x30, [sp], #32
  4005dc:	d65f03c0 	ret

00000000004005e0 <checkCPU>:

int checkCPU()
{
  4005e0:	d10043ff 	sub	sp, sp, #0x10
	   {  
			  int a;
			  char b;
	   } c;

	   c.a = 1;
  4005e4:	52800020 	mov	w0, #0x1                   	// #1
  4005e8:	b9000be0 	str	w0, [sp, #8]                ; c

	   return(c.b ==1);
  4005ec:	394023e0 	ldrb	w0, [sp, #8] ; c
  4005f0:	7100041f 	cmp	w0, #0x1
  4005f4:	1a9f17e0 	cset	w0, eq  // eq = none
  4005f8:	53001c00 	uxtb	w0, w0
    }
}
  4005fc:	910043ff 	add	sp, sp, #0x10
  400600:	d65f03c0 	ret

0000000000400604 <test_two>:

/* 
 * 高字节存储在高地址是小端，高字节存储在低地址是大端 
 */
int test_two()
{
  400604:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400608:	910003fd 	mov	x29, sp
    int *a = 1;			//	内存表示为0x00000001.
  40060c:	d2800020 	mov	x0, #0x1                   	// #1
  400610:	f9000fa0 	str	x0, [x29, #24]              ; *a

   if ((char*)&a[3] == 1)
  400614:	f9400fa0 	ldr	x0, [x29, #24] ; a
  400618:	91003000 	add	x0, x0, #0xc   ; x0 =  a + 12
  40061c:	f100041f 	cmp	x0, #0x1
  400620:	540000a1 	b.ne	400634 <test_two+0x30>  // b.any
        printf("big\n");
  400624:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400628:	91206000 	add	x0, x0, #0x818
  40062c:	97ffff81 	bl	400430 <puts@plt>
  400630:	14000004 	b	400640 <test_two+0x3c>
    else
        printf("small\n");
  400634:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400638:	91208000 	add	x0, x0, #0x820
  40063c:	97ffff7d 	bl	400430 <puts@plt>
}
  400640:	d503201f 	nop
  400644:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400648:	d65f03c0 	ret

000000000040064c <test_thr>:
 
int test_thr()
{
  40064c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400650:	910003fd 	mov	x29, sp
    {
       int a;
       short b;
    }test;

    test.a = 0x12345678;
  400654:	528acf00 	mov	w0, #0x5678                	// #22136
  400658:	72a24680 	movk	w0, #0x1234, lsl #16    ; w0 = 0x1234<<16
  40065c:	b9001ba0 	str	w0, [x29, #24]              ; test.a

    if(test.b == 0x1234)
  400660:	79c033a1 	ldrsh	w1, [x29, #24]
  400664:	52824680 	mov	w0, #0x1234                	// #4660
  400668:	6b00003f 	cmp	w1, w0
  40066c:	54000081 	b.ne	40067c <test_thr+0x30>  // b.any
      printf("big\n");
  400670:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400674:	91206000 	add	x0, x0, #0x818
  400678:	97ffff6e 	bl	400430 <puts@plt>

    if(test.b == 0x5678)
  40067c:	79c033a1 	ldrsh	w1, [x29, #24]
  400680:	528acf00 	mov	w0, #0x5678                	// #22136
  400684:	6b00003f 	cmp	w1, w0
  400688:	54000081 	b.ne	400698 <test_thr+0x4c>  // b.any
       printf("small\n");
  40068c:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400690:	91208000 	add	x0, x0, #0x820
  400694:	97ffff67 	bl	400430 <puts@plt>
}
  400698:	d503201f 	nop
  40069c:	a8c27bfd 	ldp	x29, x30, [sp], #32
  4006a0:	d65f03c0 	ret

00000000004006a4 <test_four>:


typedef unsigned char BYTE;
int test_four()
{
  4006a4:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4006a8:	910003fd 	mov	x29, sp
	unsigned int num,*p;

	p = &num;
  4006ac:	910053a0 	add	x0, x29, #0x14
  4006b0:	f9000fa0 	str	x0, [x29, #24]

	num = 0;
  4006b4:	b90017bf 	str	wzr, [x29, #20]

	*(BYTE *)p = 0xff;
  4006b8:	f9400fa0 	ldr	x0, [x29, #24]
  4006bc:	12800001 	mov	w1, #0xffffffff            	// #-1
  4006c0:	39000001 	strb	w1, [x0]

	if(num == 0xff) {
  4006c4:	b94017a0 	ldr	w0, [x29, #20]
  4006c8:	7103fc1f 	cmp	w0, #0xff
  4006cc:	540000a1 	b.ne	4006e0 <test_four+0x3c>  // b.any
		printf("The endian of cpu is little\n");
  4006d0:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  4006d4:	9120a000 	add	x0, x0, #0x828
  4006d8:	97ffff56 	bl	400430 <puts@plt>
  4006dc:	14000004 	b	4006ec <test_four+0x48>
	}
	else {		//	num == 0xff000000
		printf("The endian of cpu is big\n");
  4006e0:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  4006e4:	91212000 	add	x0, x0, #0x848
  4006e8:	97ffff52 	bl	400430 <puts@plt>
	}
	return 0;
  4006ec:	52800000 	mov	w0, #0x0                   	// #0
}
  4006f0:	a8c27bfd 	ldp	x29, x30, [sp], #32
  4006f4:	d65f03c0 	ret

00000000004006f8 <main>:


int main(void)
{
  4006f8:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4006fc:	910003fd 	mov	x29, sp
	int ret = -1;
  400700:	12800000 	mov	w0, #0xffffffff            	// #-1
  400704:	b9001fa0 	str	w0, [x29, #28]

   test_one();
  400708:	97ffffa2 	bl	400590 <test_one>

   ret = checkCPU();
  40070c:	97ffffb5 	bl	4005e0 <checkCPU>
  400710:	b9001fa0 	str	w0, [x29, #28]
   if (ret == 1)
  400714:	b9401fa0 	ldr	w0, [x29, #28]
  400718:	7100041f 	cmp	w0, #0x1
  40071c:	540000a1 	b.ne	400730 <main+0x38>  // b.any
	   printf("[little endian]\n");
  400720:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400724:	9121a000 	add	x0, x0, #0x868
  400728:	97ffff42 	bl	400430 <puts@plt>
  40072c:	14000007 	b	400748 <main+0x50>
   else if (ret == 0) 
  400730:	b9401fa0 	ldr	w0, [x29, #28]
  400734:	7100001f 	cmp	w0, #0x0
  400738:	54000081 	b.ne	400748 <main+0x50>  // b.any
	   printf("[big endian]\n");
  40073c:	90000000 	adrp	x0, 400000 <_init-0x3c8>
  400740:	9121e000 	add	x0, x0, #0x878
  400744:	97ffff3b 	bl	400430 <puts@plt>

   test_thr();
  400748:	97ffffc1 	bl	40064c <test_thr>
   test_four();
  40074c:	97ffffd6 	bl	4006a4 <test_four>


    return 0;
  400750:	52800000 	mov	w0, #0x0                   	// #0
}

/*
 * arm v7
 */
int test_one(void)
{
   1048c:	e92d4800 	push	{fp, lr}
   10490:	e28db004 	add	fp, sp, #4
   10494:	e24dd008 	sub	sp, sp, #8
    int i=1;  
   10498:	e3a03001 	mov	r3, #1
   1049c:	e50b300c 	str	r3, [fp, #-12] ; i
    char *p=(char *)&i;  
   104a0:	e24b300c 	sub	r3, fp, #12 ; r3 = fp - 12
   104a4:	e50b3008 	str	r3, [fp, #-8] ; *p

    if(*p==1)    
   104a8:	e51b3008 	ldr	r3, [fp, #-8] ; p
   104ac:	e5d33000 	ldrb	r3, [r3]  ; *p
   104b0:	e3530001 	cmp	r3, #1
   104b4:	1a000002 	bne	104c4 <test_one+0x38>
           printf("Little_endian\n");		// Little_endian
   104b8:	e59f0018 	ldr	r0, [pc, #24]	; 104d8 <test_one+0x4c>
   104bc:	ebffff92 	bl	1030c <puts@plt>
   104c0:	ea000001 	b	104cc <test_one+0x40>
    else
           printf("Big_endian\n");		// Big_endian
   104c4:	e59f0010 	ldr	r0, [pc, #16]	; 104dc <test_one+0x50>
   104c8:	ebffff8f 	bl	1030c <puts@plt>
}
   104cc:	e1a00003 	mov	r0, r3
   104d0:	e24bd004 	sub	sp, fp, #4
   104d4:	e8bd8800 	pop	{fp, pc}
   104d8:	000106b4 	.word	0x000106b4
   104dc:	000106c4 	.word	0x000106c4

000104e0 <checkCPU>:

int checkCPU()
{
   104e0:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
   104e4:	e28db000 	add	fp, sp, #0
   104e8:	e24dd00c 	sub	sp, sp, #12
	   {  
			  int a;
			  char b;
	   } c;

	   c.a = 1;
   104ec:	e3a03001 	mov	r3, #1 ; r3 = 1
   104f0:	e50b3008 	str	r3, [fp, #-8] ; c.a = 1

	   return(c.b ==1);
   104f4:	e55b3008 	ldrb	r3, [fp, #-8] ; c.b
   104f8:	e3530001 	cmp	r3, #1            ; r3 ?= 1
   104fc:	03a03001 	moveq	r3, #1        ; eq r3 = 1
   10500:	13a03000 	movne	r3, #0        ; ne r3 = 0
   10504:	e20330ff 	and	r3, r3, #255	; 0xff r3 = r3 & 0xff
    }
}
   10508:	e1a00003 	mov	r0, r3
   1050c:	e24bd000 	sub	sp, fp, #0
   10510:	e49db004 	pop	{fp}		; (ldr fp, [sp], #4)
   10514:	e12fff1e 	bx	lr

00010518 <test_two>:

/* 
 * 高字节存储在高地址是小端，高字节存储在低地址是大端 
 */
int test_two()
{
   10518:	e92d4800 	push	{fp, lr}
   1051c:	e28db004 	add	fp, sp, #4
   10520:	e24dd008 	sub	sp, sp, #8
    int *a = 1;			//	内存表示为0x00000001.
   10524:	e3a03001 	mov	r3, #1
   10528:	e50b3008 	str	r3, [fp, #-8] ; a

   if ((char*)&a[3] == 1)
   1052c:	e51b3008 	ldr	r3, [fp, #-8] ; a
   10530:	e283300c 	add	r3, r3, #12   ; r3 = 1 + 12 = 13, 见 c/array/split.c 验证
   10534:	e3530001 	cmp	r3, #1
   10538:	1a000002 	bne	10548 <test_two+0x30>
        printf("big\n");
   1053c:	e59f0018 	ldr	r0, [pc, #24]	; 1055c <test_two+0x44>
   10540:	ebffff71 	bl	1030c <puts@plt>
   10544:	ea000001 	b	10550 <test_two+0x38>
    else
        printf("small\n");
   10548:	e59f0010 	ldr	r0, [pc, #16]	; 10560 <test_two+0x48>
   1054c:	ebffff6e 	bl	1030c <puts@plt>
}
   10550:	e1a00003 	mov	r0, r3
   10554:	e24bd004 	sub	sp, fp, #4
   10558:	e8bd8800 	pop	{fp, pc}
   1055c:	000106d0 	.word	0x000106d0
   10560:	000106d4 	.word	0x000106d4

00010564 <test_thr>:
 
int test_thr()
{
   10564:	e92d4800 	push	{fp, lr}
   10568:	e28db004 	add	fp, sp, #4
   1056c:	e24dd008 	sub	sp, sp, #8
    {
       int a;
       short b;
    }test;

    test.a = 0x12345678;
   10570:	e59f304c 	ldr	r3, [pc, #76]	; 105c4 <test_thr+0x60>
   10574:	e50b3008 	str	r3, [fp, #-8]   ; test

    if(test.b == 0x1234)
   10578:	e15b30b8 	ldrh	r3, [fp, #-8] ; test
   1057c:	e1a03803 	lsl	r3, r3, #16       ; r3 = r3 << 16
   10580:	e1a03843 	asr	r3, r3, #16       ; r3 = (r3<<16)>>16
   10584:	e59f203c 	ldr	r2, [pc, #60]	; 105c8 <test_thr+0x64>
   10588:	e1530002 	cmp	r3, r2
   1058c:	1a000001 	bne	10598 <test_thr+0x34>
      printf("big\n");
   10590:	e59f0034 	ldr	r0, [pc, #52]	; 105cc <test_thr+0x68>
   10594:	ebffff5c 	bl	1030c <puts@plt>

    if(test.b == 0x5678)
   10598:	e15b30b8 	ldrh	r3, [fp, #-8]
   1059c:	e1a03803 	lsl	r3, r3, #16
   105a0:	e1a03843 	asr	r3, r3, #16
   105a4:	e59f2024 	ldr	r2, [pc, #36]	; 105d0 <test_thr+0x6c>
   105a8:	e1530002 	cmp	r3, r2
   105ac:	1a000001 	bne	105b8 <test_thr+0x54>
       printf("small\n");
   105b0:	e59f001c 	ldr	r0, [pc, #28]	; 105d4 <test_thr+0x70>
   105b4:	ebffff54 	bl	1030c <puts@plt>
}
   105b8:	e1a00003 	mov	r0, r3
   105bc:	e24bd004 	sub	sp, fp, #4
   105c0:	e8bd8800 	pop	{fp, pc}
   105c4:	12345678 	.word	0x12345678
   105c8:	00001234 	.word	0x00001234
   105cc:	000106d0 	.word	0x000106d0
   105d0:	00005678 	.word	0x00005678
   105d4:	000106d4 	.word	0x000106d4

000105d8 <test_four>:


typedef unsigned char BYTE;
int test_four()
{
   105d8:	e92d4800 	push	{fp, lr}
   105dc:	e28db004 	add	fp, sp, #4
   105e0:	e24dd008 	sub	sp, sp, #8
	unsigned int num,*p;

	p = &num;
   105e4:	e24b300c 	sub	r3, fp, #12
   105e8:	e50b3008 	str	r3, [fp, #-8] ; p, save num address

	num = 0;
   105ec:	e3a03000 	mov	r3, #0 ; num = 0
   105f0:	e50b300c 	str	r3, [fp, #-12] ; fp 0 12

	*(BYTE *)p = 0xff;
   105f4:	e51b3008 	ldr	r3, [fp, #-8] ; p ---> pointed address
   105f8:	e3e02000 	mvn	r2, #0        ; 0xff
   105fc:	e5c32000 	strb	r2, [r3]  ; *p

	if(num == 0xff) {
   10600:	e51b300c 	ldr	r3, [fp, #-12]
   10604:	e35300ff 	cmp	r3, #255	; 0xff
   10608:	1a000002 	bne	10618 <test_four+0x40>
		printf("The endian of cpu is little\n");
   1060c:	e59f001c 	ldr	r0, [pc, #28]	; 10630 <test_four+0x58>
   10610:	ebffff3d 	bl	1030c <puts@plt>
   10614:	ea000001 	b	10620 <test_four+0x48>
	}
	else {		//	num == 0xff000000
		printf("The endian of cpu is big\n");
   10618:	e59f0014 	ldr	r0, [pc, #20]	; 10634 <test_four+0x5c>
   1061c:	ebffff3a 	bl	1030c <puts@plt>
	}
	return 0;
   10620:	e3a03000 	mov	r3, #0
}
   10624:	e1a00003 	mov	r0, r3
   10628:	e24bd004 	sub	sp, fp, #4
   1062c:	e8bd8800 	pop	{fp, pc}
   10630:	000106dc 	.word	0x000106dc
   10634:	000106f8 	.word	0x000106f8

00010638 <main>:


int main(void)
{
   10638:	e92d4800 	push	{fp, lr}
   1063c:	e28db004 	add	fp, sp, #4
   10640:	e24dd008 	sub	sp, sp, #8
	int ret = -1;
   10644:	e3e03000 	mvn	r3, #0
   10648:	e50b3008 	str	r3, [fp, #-8]

   test_one();
   1064c:	ebffff8e 	bl	1048c <test_one>

   ret = checkCPU();
   10650:	ebffffa2 	bl	104e0 <checkCPU>
   10654:	e50b0008 	str	r0, [fp, #-8]
   if (ret == 1)
   10658:	e51b3008 	ldr	r3, [fp, #-8]
   1065c:	e3530001 	cmp	r3, #1
   10660:	1a000002 	bne	10670 <main+0x38>
	   printf("[little endian]\n");
   10664:	e59f0030 	ldr	r0, [pc, #48]	; 1069c <main+0x64>
   10668:	ebffff27 	bl	1030c <puts@plt>
   1066c:	ea000004 	b	10684 <main+0x4c>
   else if (ret == 0) 
   10670:	e51b3008 	ldr	r3, [fp, #-8]
   10674:	e3530000 	cmp	r3, #0
   10678:	1a000001 	bne	10684 <main+0x4c>
	   printf("[big endian]\n");
   1067c:	e59f001c 	ldr	r0, [pc, #28]	; 106a0 <main+0x68>
   10680:	ebffff21 	bl	1030c <puts@plt>

   test_thr();
   10684:	ebffffb6 	bl	10564 <test_thr>
   test_four();
   10688:	ebffffd2 	bl	105d8 <test_four>


    return 0;
   1068c:	e3a03000 	mov	r3, #0
}

#endif